﻿Option Strict On
Imports Sims3RegistryKey
Imports System.IO
Imports s3pi.Interfaces
Imports s3pi.Package
Imports s3pi.WrapperDealer
Imports System.Threading.Tasks
Public Class Form1

    'Dim m As Integer
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Icon = My.Resources.Icon
        Dim n As Integer = 0
        Try
            If IO.Directory.Exists(Path.Combine(TS3CC.Sims3MyDocFolder, "Saves")) = False Then
                MessageBox.Show("No save file found")
                'Exit Sub
                Me.Dispose()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.ToString())
        End Try
        'detect
        Dim MyDocPath As String = ""
        If TS3CC.Sims3MyDocFolder IsNot Nothing Then
            MyDocPath = TS3CC.Sims3MyDocFolder
        Else
            MessageBox.Show("Finding Sims3 folder failed, please choose sims3 folder in my document manually")
            Dim f As New FolderBrowserDialog
            f.RootFolder = Environment.SpecialFolder.MyDocuments
            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                MyDocPath = f.SelectedPath
            Else
                Me.Dispose()
            End If

        End If


        'localize
        btnBackup.Text = Localize.Localize(btnBackup.Text)
        btnClean.Text = Localize.Localize(btnClean.Text)
        btnClearMemory.Text = Localize.Localize(btnClearMemory.Text)
        btnExit.Text = Localize.Localize(btnExit.Text)
        Me.Text = Localize.Localize(Me.Text)

        'MessageBox.Show(IO.Directory.GetDirectories(Path.Combine(MyDocPath, "Saves"), "*.sims3", SearchOption.TopDirectoryOnly).Count.ToString())
        For Each strPath As String In IO.Directory.GetDirectories(Path.Combine(MyDocPath, "Saves"), "*.sims3", SearchOption.TopDirectoryOnly)



            For Each strNhd As String In IO.Directory.GetFiles(strPath, "*.nhd", SearchOption.TopDirectoryOnly)

                Try
                    'Using img As Image

                    'lstItem.SaveDir = strPath

                        '    Dim pack As IPackage = Package.OpenPackage(1, strNhd, False)
                        '    Dim SnapIcon As UInt32() = {&H6B6D837E}
                        '    Dim entrySnap As IList(Of IResourceIndexEntry) = pack.FindAll(Function(entry As IResourceIndexEntry) SnapIcon.Contains(entry.ResourceType))
                        '    Dim img As Image = Nothing
                        '    If entrySnap.Count > 1 Then
                        '        For Each entry As IResourceIndexEntry In entrySnap
                        '            Dim SnapList As IList(Of IResourceIndexEntry) = pack.FindAll(Function(entryCompared As IResourceIndexEntry) entryCompared.Instance = entry.Instance)
                        '            If SnapList.Count = 1 Then
                        '                img = Image.FromStream(WrapperDealer.GetResource(1, pack, entry).Stream)
                        '                lstItem.imgInstance = entry.Instance
                        '            End If

                        '        Next
                        '    ElseIf entrySnap.Count = 1 Then
                        '        img = Image.FromStream(WrapperDealer.GetResource(1, pack, entrySnap(0)).Stream)
                        '        lstItem.imgInstance = entrySnap(0).Instance
                        '    End If

                        '    If img IsNot Nothing Then

                        '        imgSave.Images.Add(img.GetHashCode().ToString(), img)
                        '        lstItem.ImageIndex = imgSave.Images.IndexOfKey(img.GetHashCode().ToString())

                        '        lstItem.Text += Localize.Localize("World Name: ") & lstItem.Location
                        '        Dim check As Boolean = True
                        '        For Each item As LstViewItem In lstSave.Items
                        '            If lstItem.SaveDir Is item.SaveDir Then
                        '                check = False
                        '            End If
                        '        Next
                        '        If check = True Then
                        '            lstSave.Items.Add(lstItem)
                        '            n += 1
                        '        End If

                        '    End If
                        '    img = Nothing
                        'End If

                    Dim save As New Save(strNhd)

                    Dim lstItem As New LstViewItem(strPath, save)
                    If InStr(strNhd, lstItem.Location) > 0 Then
                        imgSave.Images.Add(save.Hash, save.FamilyThum)
                        lstItem.imgInstance = save.ImgInstance
                        lstSave.Items.Add(lstItem)
                    End If
                Catch ex As Exception
                    MessageBox.Show(ex.ToString())
                End Try


            Next

        Next

    End Sub



    Private Sub bgwClean_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgwClean.DoWork
        Dim listitem As LstViewItem = DirectCast(e.Argument, LstViewItem)

        'get Oldsize
        Dim OldfileSize As Long = 0
        For Each filePath As String In IO.Directory.GetFiles(listitem.SaveDir, "*.*", SearchOption.AllDirectories)
            OldfileSize += My.Computer.FileSystem.GetFileInfo(filePath).Length
        Next



        'Compress the save
        'For Each toCompress As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
        '    Dim pack As IPackage = Package.OpenPackage(1, toCompress, True)
        '    For Each entry As IResourceIndexEntry In pack.GetResourceList
        '        If entry.Compressed = &H0 Then
        '            entry.Compressed = &HFFFF
        '        End If
        '        If entry.ResourceType = &H580A2CE Or entry.ResourceType = &H580A2CD Then
        '            pack.DeleteResource(entry)
        '        End If
        '    Next
        '    pack.SavePackage()
        '    Package.ClosePackage(1, pack)
        'Next

        bgwClean.ReportProgress(0, "Compressing Save...")

        For Each toCompress As String In IO.Directory.GetFiles(listitem.SaveDir, "*.package", SearchOption.AllDirectories)
            Dim pack As IPackage = Package.OpenPackage(1, toCompress, True)
            For Each entry As IResourceIndexEntry In pack.GetResourceList
                If entry.Compressed = &H0 Then
                    entry.Compressed = &HFFFF
                End If
            Next
            pack.SavePackage()
            Package.ClosePackage(1, pack)
        Next

        If IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories).Count > 1 Then
            'For Each strPath As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
            '    If Path.GetFileNameWithoutExtension(strPath).Contains(listitem.Location) = False Then
            '        Dim pack As IPackage = Package.OpenPackage(1, strPath, True)
            '        For Each entry As IResourceIndexEntry In pack.GetResourceList
            '            If entry.ResourceType = &HB2D882 AndAlso entry.Memsize = &H2AB38 Then
            '                pack.DeleteResource(entry)
            '            End If
            '        Next
            '        pack.SavePackage()
            '        Package.ClosePackage(1, pack)
            '    End If
            'Next

            'This is for a test
            'Note I delete the imgs from travelDB. if it doesn's works, then you need to
            'delete the duplicated from nhd, rather than travelDB
            bgwClean.ReportProgress(0, "Clearing Duplicated Images...")

            Dim SameList As New List(Of IResourceIndexEntry)
            'Dim travelList As New List(Of IResourceIndexEntry)
            'Dim travelSize As New List(Of ULong)

            Dim TravelDB As IPackage = Package.OpenPackage(1, Path.Combine(listitem.SaveDir, "TravelDB.package"), True)
            For Each entry As IResourceIndexEntry In TravelDB.GetResourceList
                If entry.ResourceType = &HB2D882 AndAlso (entry.Memsize = &H2AB38 Or entry.Memsize = &HAB38) Then
                    'If OneList.Contains(entry.Instance) = False Then
                    SameList.Add(entry)
                    'If travelSize.Contains(entry.Filesize) = False Then

                    '    travelSize.Add(entry.Filesize)
                    'Else
                    '    travelList.Add(entry)
                    'End If
                    'End If
                End If
            Next

            For Each strPath As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
                If Path.GetFileNameWithoutExtension(strPath).Contains(listitem.Location) = True Then
                    Dim pack As IPackage = Package.OpenPackage(1, strPath, True)
                    For Each entry As IResourceIndexEntry In pack.GetResourceList

                        For Each entryCompare As IResourceIndexEntry In SameList
                            If entryCompare.Filesize = entry.Filesize Then
                                TravelDB.DeleteResource(entryCompare)
                            End If

                        Next

                        If (entry.Instance <> listitem.imgInstance) AndAlso (entry.ResourceType.Equals(&H6B6D837E)) Then
                            pack.DeleteResource(entry)
                        End If

                        If entry.Compressed = &H0 Then
                            entry.Compressed = &HFFFF
                        End If

                        If entry.ResourceType = &H580A2CE Or entry.ResourceType = &H580A2CD Then
                            pack.DeleteResource(entry)
                        End If
                    Next
                    bgwClean.ReportProgress(0, "Saving Save...")
                    pack.SavePackage()
                    Package.ClosePackage(0, pack)
                Else

                    Dim pack As IPackage = Package.OpenPackage(1, strPath, True)
                    For Each entry As IResourceIndexEntry In pack.GetResourceList


                        If entry.Compressed = &H0 Then
                            entry.Compressed = &HFFFF
                        End If
                        If entry.ResourceType = &H580A2CE Or entry.ResourceType = &H580A2CD Then
                            pack.DeleteResource(entry)
                        End If

                        If entry.ResourceType = &HB2D882 AndAlso (entry.Memsize = &H2AB38 Or entry.Memsize = &HAB38) Then
                            pack.DeleteResource(entry)
                        End If

                    Next
                    bgwClean.ReportProgress(0, "Saving Save...")
                    pack.SavePackage()
                    Package.ClosePackage(0, pack)
                End If
            Next

            TravelDB.SavePackage()

            Package.ClosePackage(1, TravelDB)
        Else
            For Each toCompress As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
                Dim pack As IPackage = Package.OpenPackage(1, toCompress, True)
                bgwClean.ReportProgress(0, "Compressing Save...")
                For Each entry As IResourceIndexEntry In pack.GetResourceList
                    If entry.Compressed = &H0 Then
                        entry.Compressed = &HFFFF
                    End If
                    If entry.ResourceType = &H580A2CE Or entry.ResourceType = &H580A2CD Then
                        pack.DeleteResource(entry)
                    End If
                Next
                bgwClean.ReportProgress(0, "Saving Save...")
                pack.SavePackage()
                Package.ClosePackage(1, pack)
            Next
        End If


        ' Calculate the size change
        Dim NewfileSize As Long = 0
        For Each filePath As String In IO.Directory.GetFiles(listitem.SaveDir, "*.*", SearchOption.AllDirectories)
            NewfileSize += My.Computer.FileSystem.GetFileInfo(filePath).Length
        Next

        Dim oldSize As Double = (OldfileSize / 1024) / 1024
        Dim newSize As Double = (NewfileSize / 1024) / 1024

        Dim size As New SizeInt(oldSize, newSize)

       
        e.Result = size
        
    End Sub

    Private Class SizeInt
        Public Property OldSize As Double
        Public Property NewSize As Double
        Public Sub New(ByVal oldsize As Double, ByVal newsize As Double)
            Me.OldSize = oldsize
            Me.NewSize = newsize
        End Sub
    End Class

    Private Sub btnClean_Click(sender As Object, e As EventArgs) Handles btnClean.Click
        Try
            'Dim imgList As New List(Of ULong)
            For Each listitem As LstViewItem In lstSave.SelectedItems
                ''get Oldsize
                'Dim OldfileSize As Long = 0
                'For Each filePath As String In IO.Directory.GetFiles(listitem.SaveDir, "*.*", SearchOption.AllDirectories)
                '    OldfileSize += My.Computer.FileSystem.GetFileInfo(filePath).Length
                'Next



                ''Compress the save
                ''For Each toCompress As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
                ''    Dim pack As IPackage = Package.OpenPackage(1, toCompress, True)
                ''    For Each entry As IResourceIndexEntry In pack.GetResourceList
                ''        If entry.Compressed = &H0 Then
                ''            entry.Compressed = &HFFFF
                ''        End If
                ''        If entry.ResourceType = &H580A2CE Or entry.ResourceType = &H580A2CD Then
                ''            pack.DeleteResource(entry)
                ''        End If
                ''    Next
                ''    pack.SavePackage()
                ''    Package.ClosePackage(1, pack)
                ''Next

                'For Each toCompress As String In IO.Directory.GetFiles(listitem.SaveDir, "*.package", SearchOption.AllDirectories)
                '    Dim pack As IPackage = Package.OpenPackage(1, toCompress, True)
                '    For Each entry As IResourceIndexEntry In pack.GetResourceList
                '        If entry.Compressed = &H0 Then
                '            entry.Compressed = &HFFFF
                '        End If
                '    Next
                '    pack.SavePackage()
                '    Package.ClosePackage(1, pack)
                'Next

                'If IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories).Count > 1 Then
                '    'For Each strPath As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
                '    '    If Path.GetFileNameWithoutExtension(strPath).Contains(listitem.Location) = False Then
                '    '        Dim pack As IPackage = Package.OpenPackage(1, strPath, True)
                '    '        For Each entry As IResourceIndexEntry In pack.GetResourceList
                '    '            If entry.ResourceType = &HB2D882 AndAlso entry.Memsize = &H2AB38 Then
                '    '                pack.DeleteResource(entry)
                '    '            End If
                '    '        Next
                '    '        pack.SavePackage()
                '    '        Package.ClosePackage(1, pack)
                '    '    End If
                '    'Next

                '    'This is for a test
                '    'Note I delete the imgs from travelDB. if it doesn's works, then you need to
                '    'delete the duplicated from nhd, rather than travelDB

                '    Dim SameList As New List(Of IResourceIndexEntry)
                '    'Dim travelList As New List(Of IResourceIndexEntry)
                '    'Dim travelSize As New List(Of ULong)

                '    Dim TravelDB As IPackage = Package.OpenPackage(1, Path.Combine(listitem.SaveDir, "TravelDB.package"), True)
                '    For Each entry As IResourceIndexEntry In TravelDB.GetResourceList
                '        If entry.ResourceType = &HB2D882 AndAlso (entry.Memsize = &H2AB38 Or entry.Memsize = &HAB38) Then
                '            'If OneList.Contains(entry.Instance) = False Then
                '            SameList.Add(entry)
                '            'If travelSize.Contains(entry.Filesize) = False Then

                '            '    travelSize.Add(entry.Filesize)
                '            'Else
                '            '    travelList.Add(entry)
                '            'End If
                '            'End If
                '        End If
                '    Next

                '    For Each strPath As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
                '        If Path.GetFileNameWithoutExtension(strPath).Contains(listitem.Location) = True Then
                '            Dim pack As IPackage = Package.OpenPackage(1, strPath, True)
                '            For Each entry As IResourceIndexEntry In pack.GetResourceList

                '                For Each entryCompare As IResourceIndexEntry In SameList
                '                    If entryCompare.Filesize = entry.Filesize Then
                '                        TravelDB.DeleteResource(entryCompare)
                '                    End If

                '                Next

                '                If (entry.Instance <> listitem.imgInstance) AndAlso (entry.ResourceType.Equals(&H6B6D837E)) Then
                '                    pack.DeleteResource(entry)
                '                End If

                '                If entry.Compressed = &H0 Then
                '                    entry.Compressed = &HFFFF
                '                End If

                '                If entry.ResourceType = &H580A2CE Or entry.ResourceType = &H580A2CD Then
                '                    pack.DeleteResource(entry)
                '                End If
                '            Next
                '            pack.SavePackage()
                '            Package.ClosePackage(0, pack)
                '        Else

                '            Dim pack As IPackage = Package.OpenPackage(1, strPath, True)
                '            For Each entry As IResourceIndexEntry In pack.GetResourceList


                '                If entry.Compressed = &H0 Then
                '                    entry.Compressed = &HFFFF
                '                End If
                '                If entry.ResourceType = &H580A2CE Or entry.ResourceType = &H580A2CD Then
                '                    pack.DeleteResource(entry)
                '                End If

                '                If entry.ResourceType = &HB2D882 AndAlso (entry.Memsize = &H2AB38 Or entry.Memsize = &HAB38) Then
                '                    pack.DeleteResource(entry)
                '                End If

                '            Next
                '            pack.SavePackage()
                '            Package.ClosePackage(0, pack)
                '        End If
                '    Next

                '    TravelDB.SavePackage()

                '    Package.ClosePackage(1, TravelDB)
                'Else
                '    For Each toCompress As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
                '        Dim pack As IPackage = Package.OpenPackage(1, toCompress, True)
                '        For Each entry As IResourceIndexEntry In pack.GetResourceList
                '            If entry.Compressed = &H0 Then
                '                entry.Compressed = &HFFFF
                '            End If
                '            If entry.ResourceType = &H580A2CE Or entry.ResourceType = &H580A2CD Then
                '                pack.DeleteResource(entry)
                '            End If
                '        Next
                '        pack.SavePackage()
                '        Package.ClosePackage(1, pack)
                '    Next
                'End If


                '' Calculate the size change
                'Dim NewfileSize As Long = 0
                'For Each filePath As String In IO.Directory.GetFiles(listitem.SaveDir, "*.*", SearchOption.AllDirectories)
                '    NewfileSize += My.Computer.FileSystem.GetFileInfo(filePath).Length
                'Next

                'Dim oldSize As Double = (OldfileSize / 1024) / 1024
                'Dim newSize As Double = (NewfileSize / 1024) / 1024

                'MessageBox.Show(Localize.Localize("Save clean has been completed!") & vbNewLine & Localize.Localize("I have shrunk your save from  ") & _
                '                 Format(oldSize, "0.00") & Localize.Localize(" MB to  ") & Format(newSize, "0.00") & " MB." & vbNewLine & _
                '                 Localize.Localize("The percentage is  ") & FormatPercent((oldSize - newSize) / oldSize, 2), Localize.Localize("Congratulations!"))

                bgwClean.RunWorkerAsync(listitem)
                Waiting.Show()
                Waiting.Focus()
            Next



        Catch ex As Exception
            ex.ToString()
        End Try
        GC.Collect()
    End Sub

    Private Sub btnClearMemory_Click(sender As Object, e As EventArgs) Handles btnClearMemory.Click
        If MessageBox.Show(Localize.Localize("Before clear all memories, make sure you have disable memory in the game."), Localize.Localize("Attention"), MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
            For Each listitem As LstViewItem In lstSave.SelectedItems
                For Each STRPackToDelete As String In IO.Directory.GetFiles(listitem.SaveDir, "*.nhd", SearchOption.AllDirectories)
                    Dim packToDelete As IPackage = Package.OpenPackage(1, STRPackToDelete, True)

                    For Each entry As IResourceIndexEntry In packToDelete.GetResourceList
                        If entry.Memsize = &H2AB38 Then
                            packToDelete.DeleteResource(entry)
                        End If
                    Next
                    packToDelete.SavePackage()
                    Package.ClosePackage(1, packToDelete)
                Next
                For Each STRPackToDelete As String In IO.Directory.GetFiles(listitem.SaveDir, "*.package", SearchOption.AllDirectories)
                    Dim packToDelete As IPackage = Package.OpenPackage(1, STRPackToDelete, True)

                    For Each entry As IResourceIndexEntry In packToDelete.GetResourceList
                        If entry.Memsize = &H2AB38 Then
                            packToDelete.DeleteResource(entry)
                        End If
                    Next
                    packToDelete.SavePackage()
                    Package.ClosePackage(1, packToDelete)
                Next
            Next
            MessageBox.Show(Localize.Localize("All memory has been deleted!"))
        End If

    End Sub

    Private Sub btnBackup_Click(sender As Object, e As EventArgs) Handles btnBackup.Click
        Dim fileDialoge As New FolderBrowserDialog
        With fileDialoge
            .ShowNewFolderButton = True
            .Description = Localize.Localize("Please choose the folder to which you want to put your save. Please note that this is an auto-overwrite function")
        End With
        If fileDialoge.ShowDialog = Windows.Forms.DialogResult.OK Then
            For Each listitem As LstViewItem In lstSave.SelectedItems
                My.Computer.FileSystem.CopyDirectory(listitem.SaveDir, fileDialoge.SelectedPath, True)

            Next
            MessageBox.Show(Localize.Localize("Save has been backup!"))
        End If
    End Sub

    Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
        Me.Dispose()
    End Sub

    Private Sub bgwClean_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgwClean.RunWorkerCompleted
        Dim size As SizeInt = DirectCast(e.Result, SizeInt)
        Dim oldSize As Double = size.OldSize
        Dim newSize As Double = size.NewSize
        Waiting.Dispose()
        MessageBox.Show(Localize.Localize("Save clean has been completed!") & vbNewLine & Localize.Localize("I have shrunk your save from  ") & _
                        Format(oldSize, "0.00") & Localize.Localize(" MB to  ") & Format(newSize, "0.00") & " MB." & vbNewLine & _
                        Localize.Localize("The percentage is  ") & FormatPercent((oldSize - newSize) / oldSize, 2), Localize.Localize("Congratulations!"))


    End Sub

    Private Sub bgwClean_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwClean.ProgressChanged
        Waiting.lblText.Text = e.UserState.ToString()
    End Sub
End Class
